<?php
/**
 * Created by 张彪.
 * User: 小马出行
 * Date: 2018/7/30
 * Time: 9:21
 */
namespace app\index\controller;

use app\api\logic\TripLogic;
use app\index\logic\LocalLogic;
use my\Define;
use my\ElasticSearch;
use my\Security;
use think\Controller;
use think\Db;
use think\Env;

class Driver extends Controller
{
    public $img_point = "webapi.amap.com/ui/1.0/ui/misc/PointSimplifier/examples/imgs/";
    public $img_path = "webapi.amap.com/ui/1.0/ui/misc/PathSimplifier/examples/imgs/";
    public $field_inner = "d.driver_id,driver_status";//,car_plate,car_model,car_brand,color";
    public $field_inter = "d.id as driver_id,is_goon as driver_status";//,car_plate,car_model,car_brand,car_color as color";
    public $max_result_window = 500;//最大返回数
    public $mongo_options = array();//MongoDB连接参数

    public function _initialize()
    {
        $this->mongo_options = config('mongodb');
    }

    //车联网首页--加载当前区域
    public function index()
    {
        $config['protocol'] = PROTOCOL;
        $config['gd_key'] = config('GD_WEB');
        $config['url'] = url('local');
        $config['url_all'] = url('getLocalMd');
        $config['url_order'] = url('getOrderInfo');
        $config['url_plate'] = url('searchPlate');
        $config['url_page'] = url('getPageMd');
        $config['offline'] = Define::FTP_URL."/public/images/offline_car.png";
        $config['order'] = Define::FTP_URL."/public/images/order_taking.png";
        $config['trip'] = Define::FTP_URL."/public/images/trip.png";
        $config['provinces'] = $this->getRegion(1);

        $this->assign($config);
        return view();
    }

    //某一司机地理位置
    public function local()
    {
        $config['driver_id'] = input('get.driver_id');
        $config['auth_type'] = input('get.auth_type');
        if(empty($config['driver_id']) || empty($config['auth_type'])){
            return "<script>alert('缺少参数');</script>";
        }
        if($config['auth_type'] == 3){
            $driver = Db::connect(config('intercity_db'))->name('driver d')->join('car_list cl','d.id = cl.driver','LEFT')
                ->where('d.id',$config['driver_id'])->field('driver_name,body_img,body_img_thumb,car_plate')->find();
        }else{
            $driver = Db::name('driver d')->join('car_info ci','d.driver_id = ci.driver_id','LEFT')
                ->where('d.driver_id',$config['driver_id'])->where('record_status',2)
                ->field('driver_name,body_img,body_img_thumb,car_plate')->find();
            $driver = decode_array($driver);
        }
        $config['protocol'] = PROTOCOL;
        $config['gd_key'] = config('GD_WEB');
        $config['title'] = "司机{$driver['driver_name']}当前位置";
        $config['body_img'] = $driver['body_img_thumb']?:"/public/img.png";
        $config['car_plate'] = $driver['car_plate'];
        switch ($config['auth_type']){
            case 1:
                //专车
                $icon_img = Define::FTP_URL."/public/images/car_special.png";
                break;
            case 2:
            case 3:
                //出租车
                $icon_img = Define::FTP_URL."/public/images/car_taxi.png";
                break;
            default:
                $icon_img = PROTOCOL."webapi.amap.com/theme/v1.3/markers/n/mark_b.png";
                break;
        }
        $config['icon_img'] = $icon_img;
        $config['url'] = array('coordinate'=>url('getCoordinateMd'),'trajectory'=>url('trajectory'));
        $this->assign($config);
        return view();
    }

    //获取司机坐标
    public function getCoordinate()
    {
        $map['driver_id'] = (int)input('post.driver_id');
        $map['auth_type'] = (int)input('post.auth_type');
        if(empty($map['driver_id'])|| empty($map['auth_type'])) return json(array('status'=>0,'msg'=>'缺少参数'));
        $elk = new ElasticSearch();
        $params = config('elastic')['es']['actual_param'];
        $body = ["query"=>
                ["bool"=>
                    ["filter"=>
                        [
                            ["term"=>
                                ["driver_id"=>$map['driver_id']]
                            ],
                            ["term"=>
                                ["auth_type"=>$map['auth_type']]
                            ]
                        ]
                    ]
                ]
            ];
        $result =  $elk->searchDoc($params['index'],$params['type'],$body);
        if($result['status']!=1){
            return json(array('status'=>0,'msg'=>$result['msg']));
        }
        $location = $result['data'][0];
        $location['avg_s'] = 60;
        return json(array('status'=>1,'data'=>$location));
    }

    //获取司机坐标--mongodb
    public function getCoordinateMd()
    {
        $map['driverId'] = (int)input('post.driver_id');
        $map['authType'] = (int)input('post.auth_type');
        if(empty($map['driverId'])|| empty($map['authType'])){
            return json(array('status'=>0,'msg'=>'缺少参数'));
        }
        $result = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->field('_id,_class,addTime',true)->find();
        if(empty($result)){
            return json(array('status'=>0,'msg'=>'没有该司机的实时坐标'));
        }
        return json(array('status'=>1,'data'=>$result));
    }

    //获取司机轨迹
    public function trajectory()
    {
        $data_post = input('post.');
        $elk = new ElasticSearch();
        $start = $data_post['date']." 00:00:00";
        $end = $data_post['date']." 23:59:59";
        $params = config('elastic')['es']['index_param'];
        $index = $params['index'];
        $type = $params['type'];
        $body =
            ["query"=>
                ["bool"=>
                    ["filter"=>
                        [
                            ["term"=>
                                ["driverId"=>(int)$data_post['driver_id']]
                            ],
                            ["term"=>
                                ["authType"=>(int)$data_post['auth_type']]
                            ],
                            ["range"=>
                                ["addTime"=>
                                    [
                                        "gte"=>$start,
                                        "lte"=>$end,
                                    ]
                                ]
                            ]
                        ]
                    ]
                ]
            ];
        $result = $elk->searchDoc($index,$type,$body,1,true,array('addTime'=>'asc'));
        if($result['status']!=1){
            $return['status'] = 0;
            $return['msg'] = '没有查到相关数据';
            return json($return);
        }
        $index = 0;
        foreach ($result['data'] as $key => $val){
            if($val['coordinate']['lat']=='0.0' || $val['coordinate']['lon']=='0.0' || empty($val['coordinate']['lon']) || empty($val['coordinate']['lat'])){
                continue;
            }
            $data[$index][] = $val['coordinate']['lon'];
            $data[$index][] = $val['coordinate']['lat'];
            $index++;
        }
        $return['status'] = 1;
        $return['coordinate'] = $data;
        return json($return);
    }

    //获取所有司机坐标信息--mongodb
    public function getLocalMd()
    {
        $driver_combine = $data =array();
        $data_post = input('post.');
        switch ($data_post['type']){
            case 'plate'://车牌搜索
                if($data_post['inner']){
                    foreach ($data_post['inner'] as $key => $val){
                        $inner_driver_id[] = (int)$val['driver_id'];
                    }
                    $map['driverId'] = array('in',$inner_driver_id);
                    $map['authType'] = array('in',array(1,2));
                    $inner_local = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->select();
                }
                if($data_post['inter']){
                    foreach ($data_post['inter'] as $key => $val){
                        $inter_driver_id[] = (int)$val['driver_id'];
                    }
                    $map['driverId'] = array('in',$inter_driver_id);
                    $map['authType'] = 3;
                    $inter_local = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->select();
                }
                $inner_local && $data = array_merge($data,$inner_local);
                $inter_local && $data = array_merge($data,$inter_local);
                $driver_combine['sta'] = '';
                $driver_combine['data'] = $data;
                break;
            default:
                $map['location'] = array('geo within',array('$box'=>json_decode($data_post['bounds'],true)));
                $map_inner['authType'] = array('in',array(1,2));$map_inter['authType'] = 3;
                $driver_combine['data'] = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)
                    ->page($data_post['page'],$this->max_result_window)->field('_id,_class,addTime',true)->select();
                if($data_post['page']==1){
                    $driver_combine['sta']['total'] = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->count();
                    $inner_taking = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->where($map_inner)->where('driverStatus',1)->count();
                    $inner_trip = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->where($map_inner)->where('driverStatus','in',[2,3,4])->count();
                    $inner_offline = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->where($map_inner)->where('driverStatus','in',[0,5])->count();
                    $inter_taking = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->where($map_inter)->where('driverStatus',2)->count();
                    $inter_trip = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->where($map_inter)->where('driverStatus','in',[1,3])->count();
                    $inter_offline = Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->where($map_inter)->where('driverStatus',4)->count();
                    $driver_combine['sta']['trip'] = $inner_trip + $inter_trip;
                    $driver_combine['sta']['taking'] = $inner_taking + $inter_taking;
                    $driver_combine['sta']['offline'] = $inner_offline + $inter_offline;
                }
                break;
        }
        if(empty($driver_combine['data'])){
            return json(array('status'=>0,'msg'=>'当前条件暂无车辆','sta'=>$driver_combine['sta']));
        }
        return json(array('status'=>1,'data'=>$driver_combine['data'],'sta'=>$driver_combine['sta']));
    }

    //获取所有司机坐标信息--elasticsearch
    public function getLocalES()
    {
        $data_post = input('post.');
        if(!in_array($data_post['from'],array('inner','inter'))){
            return json(array('status'=>0,'msg'=>'司机参数错误'));
        }
        $driver_combine = $data =array();
        $elk = new ElasticSearch();
        $local_logic = new LocalLogic();
        $params = config('elastic')['es']['actual_param'];
        switch ($data_post['type']){
            case 'plate':
                $total = 0;
                $where = array();
                if($data_post['inner']){
                    $inner_driver = $local_logic->dealDriverInfo($data_post['inner']);
                    $where['inner'] = $inner_driver['driver_id'];
                    $body['query']['bool']['filter'][]['term'] = ['driver_id'=>$inner_driver['driver_id'][0]];
                    $body['query']['bool']['filter'][]['range'] = ['auth_type'=>["lt"=>3]];
                    $total += count($inner_driver['driver_id']);unset($inner_driver['driver_id']);
                    $inner_local = $elk->searchDoc($params['index'],$params['type'],$body)['data'];
                    $inner_local = $local_logic->dealDriverInfoLocation($inner_driver,$inner_local);
                }
                if($data_post['inter']){
                    $inter_driver = $local_logic->dealDriverInfo($data_post['inter']);
                    $where['inter'] = $inter_driver['driver_id'];
                    $body['query']['bool']['filter'][]['term'] = ['driver_id'=>$inter_driver['driver_id'][0]];
                    $body['query']['bool']['filter'][]['term'] = ['auth_type'=>3];
                    $total += count($inter_driver['driver_id']);unset($inter_driver['driver_id']);
                    $inter_local = $elk->searchDoc($params['index'],$params['type'],$body)['data'];
                    $inter_local = $local_logic->dealDriverInfoLocation($inter_driver,$inter_local);
                }
                $inner_local && $data = array_merge($data,$inner_local);
                $inter_local && $data = array_merge($data,$inter_local);
                $driver_combine['sta'] = $local_logic->statistics($where);
                $driver_combine['sta']['total'] = $total;
                $driver_combine['data'] = $data;
                break;
            default:
                $box = json_decode($data_post['bounds'],true);
                $body['inner'] = $body['inter'] =
                    ["query"=>
                        ["bool"=>
                            [
                                "must"=>
                                    ["match_all"=>new \stdClass()],
                                "filter"=>[
                                    ["geo_bounding_box"=>
                                        ["coordinate" =>
                                            [
                                                "top_right"=>$box[0],
                                                "bottom_left"=>$box[1]
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ];
                $body['inner']["query"]["bool"]["filter"][1] = ["range"=> ["auth_type"=> ["lt"=>3]]];
                $body['inter']["query"]["bool"]["filter"][1] = ["term"=> ["auth_type"=> 3]];
                $result = $elk->searchDoc($params['index'],$params['type'],$body[$data_post['from']],$data_post['page'],false,array(),'driver_id');
                if($result['status']!=1){
                    return json($result);
                }
                $data[$data_post['from']."_driver_id"] = $result['data']['driver_id'];unset($result['data']['driver_id']);
                $data[$data_post['from']] = $result['data'];
                $driver_combine = $local_logic->dealDriverLocation($data,array('inner'=>$this->field_inner,'inter'=>$this->field_inter));
                break;
        }

        if(empty($driver_combine['data'])){
            return json(array('status'=>0,'msg'=>'当前条件暂无车辆','sta'=>$driver_combine['sta']));
        }
        $driver_combine['status'] = 1;
        return json($driver_combine);
    }

    //获取司机订单信息
    public function getOrderInfo()
    {
        $data_post = input('post.');
        $map['driver_id'] = $data_post['driver_id'];
        if(empty($data_post['auth_type']) || empty($map['driver_id'])){
            return json(array('status'=>0,'msg'=>'缺少参数'));
        }
        $local_logic = new LocalLogic();
        if(in_array($data_post['auth_type'],array(1,2))){
            $map['order_status'] = array('in',array(20,30,40));
            $info = $local_logic->getInnerOrderInfo($map,'order_sn,passenger_phone,order_time,on_car_time');
        }else{
            $info = $local_logic->getInterOrderInfo($map,'order_sn,contact_number as passenger_phone,order_time,dep_time as on_car_time');
        }
        if(empty($info)){
            return json(array('status'=>0,'msg'=>'没有对应的订单'));
        }
        $info['order_time'] = $info['order_time'] ? date('Y.m.d H:i',$info['order_time']) : '';
        $info['on_car_time'] = $info['on_car_time'] ? date('Y.m.d H:i',$info['on_car_time']) : '';
        $this->assign($info);
        $this->assign($data_post);
        return json(array('status'=>1,'html'=>$this->fetch('info'),'data'=>$info));
    }

    //车牌搜索
    public function searchPlate()
    {
        $local_logic = new LocalLogic();
        $car_plate = input('post.plate');
        $map_inner['record_status'] = 2;
        $map_inner['car_plate'] = Security::encrypt($car_plate);
        $map_inner['auth_status'] = $map_inter['auth_status'] = 1;
        $map_inter['car_plate'] = $car_plate;
        $inner = $local_logic->searchInnerDriver($map_inner,$this->field_inner);
        $inter = $local_logic->searchInterDriver($map_inter,$this->field_inter);
        if(empty($inner)&&empty($inter)){
            return json(array('status'=>0,'msg'=>'该车牌号不存在'));
        }
        return json(array('status'=>1,'inner'=>$inner,'inter'=>$inter));
    }

    //获取区域
    public function getRegion($pid=0)
    {
        $map['parent_id'] = $pid ? : input('post.parent_id');
        $type = input('post.type');
        if((empty($map['parent_id']) || !in_array($type,array('city','area'))) && empty($pid)){
            return json(array('status'=>0,'msg'=>'参数缺失'));
        }
        switch ($type){
            case 'city':
                $region = Db::name('region')->where($map)->field('region_id,region_name')->select();
                break;
            case 'area':
                $map['region_name'] = array('neq',"市辖区");
                $region = Db::name('region')->where($map)->field('region_id,region_name')->select();
                break;
            default:
                $region = Db::name('region')->where($map)->field('region_id,region_name')->select();
                break;
        }
        return $pid ? $region : json(array('status'=>1,'data'=>$region));
    }

    //区域搜索
    /*public function searchDriverByRegion()
    {
        $local_logic = new LocalLogic();
        $data_post = input('post.');
        $data_post['province'] && $map['work_province'] = $data_post['province'];
        $data_post['city'] && $map['work_city'] = $data_post['city'];
        $data_post['area'] && $map['work_county'] = $data_post['area'];
        $map['work_province'] && $map['auth_status'] = 1;
        $inner = $local_logic->searchInnerDriver($map,$this->field_inner);
        $inter = $local_logic->searchInterDriver($map,$this->field_inter);
        if(empty($inner)&&empty($inter)){
            return json(array('status'=>0,'msg'=>'该区域没有司机'));
        }
        return json(array('status'=>1,'inner'=>$inner,'inter'=>$inter));
    }*/

    //获取区域内的司机分页显示页数--elasticsearch
    public function getPage()
    {
        $data_post = input('post.');
        $elk = new ElasticSearch();
        $params = config('elastic')['es']['actual_param'];
        $box = json_decode($data_post['bounds'],true);
        $body_inner = $body_inter =
            ["query"=>
                ["bool"=>
                    [
                        /*"must"=>
                            ["match_all"=>new \stdClass()],*/
                        "filter"=>[
                            ["geo_bounding_box"=>
                                ["coordinate" =>
                                    [
                                        "top_right"=>$box[0],
                                        "bottom_left"=>$box[1]
                                    ]
                                ]
                            ]
                        ]
                    ]
                ]
            ];
        $body_inner["query"]["bool"]["filter"][1] = ["range"=> ["auth_type"=> ["lt"=>3]]];
        $body_inter["query"]["bool"]["filter"][1] = ["term"=> ["auth_type"=> 3]];
        $data['inner'] = ceil($elk->count($params['index'],$params['type'],$body_inner)/$elk->max_result_window);
        $data['inter'] = ceil($elk->count($params['index'],$params['type'],$body_inter)/$elk->max_result_window);
        return json($data);
    }

    //获取区域内的司机分页显示页数--mongodb
    public function getPageMd()
    {
        $data_post = input('post.');
        if($data_post['type']=='plate'){
            return json(array('page'=>1));
        }
        $map['location'] = array('geo within',array('$box'=>json_decode($data_post['bounds'],true)));
        $data['page'] = ceil(Db::connect($this->mongo_options)->table('live_driver_location')->where($map)->count()/$this->max_result_window);
        return json($data);
    }

    public function test()
    {
        $elk = new ElasticSearch();
        $params = config('elastic')['es']['actual_param'];
        /*$local_arr = explode("\n",file_get_contents('./10w.txt'));
        foreach ($local_arr as $key => $value){
            $data[$key]['driver_id'] = $key+1;
            $local = explode(',',$value);
            $data[$key]['coordinate'] = array((float)$local[0],(float)$local[1]);
            $data[$key]['auth_type'] = rand(1,3);
            $data[$key]['speed'] = rand(10,60);
            $data[$key]['direction'] = rand(0,360);
            if($key%1000 == 0){
                $result = $elk->bulkDoc($params['index'],$params['type'],$data);
                //删除旧的批量请求
                $data = [];
                //完成节省内存后取消设置批量响应
                unset($result);
            }
        }
        if(!empty($data)){
            $result = $elk->bulkDoc($params['index'],$params['type'],$data);
        }*/
        $field = 'coordinate';
        $box = array(array(124.724906,49.434168),array(94.490531,20.625029));
//        $result = $elk->searchGeoBoxDoc($params['index'],$params['type'],$field,$box,1,true,array('driver_id','_id'),array('driver_id','auth_type'));
        $filter = array(array('term'=>array('driver_id'=>66)),array('term'=>array('auth_type'=>1)));
       /* $search = $elk->getDocId($params['index'],$params['type'],$filter,false);
        if($search['status']==1){
            $body = array("doc"=>array('speed'=>15,'direction'=>30));
            $result = $elk->updateDoc($params['index'],$params['type'],$search['data'],$body);
        }elseif($search['status']==2){
            $body = array('speed'=>15,'direction'=>30,'driver_id'=>111111,'auth_type'=>1,'coordinate'=>[117.123456,31.654321]);
            $result = $elk->createDoc($params['index'],$params['type'],'',$body);
        }*/
        $body =
            ["query"=>
                ["bool"=>
                    ["filter"=>
                        [
                            ["term"=>
                                ["driver_id"=>49018]
                            ],
                            ["term"=>
                                ["auth_type"=>2]
                            ]
                        ]
                    ]
                ]
            ];
        $result = $elk->searchDoc($params['index'],$params['type'],$body);
        print_r($result);

    }

    public function testMd()
    {
        $mongo = db('driver_location',$this->mongo_options);
        $local_arr = explode("\n",file_get_contents('./10w.txt'));
        foreach ($local_arr as $key => $value){
            $data[$key]['driverId'] = $key+1;
            $local = explode(',',$value);
            $data[$key]['location']['coordinates'] = array((float)$local[0],(float)$local[1]);
            $data[$key]['location']['type'] = 'Point';
            $data[$key]['authType'] = rand(1,3);
            if($data[$key]['authType']==3){
                $data[$key]['driverStatus'] = rand(1,4);
            }else{
                $data[$key]['driverStatus'] = rand(0,5);
            }
            $data[$key]['speed'] = rand(10,60);
            $data[$key]['direction'] = rand(0,360);
            $data[$key]['addTime'] = time();
            $data[$key]['_class'] = CONTROLLER_NAME.'/'.ACTION_NAME;
            if($key%1000 == 0){
//                $result = $mongo->insertAll($data);
                //删除旧的批量请求
                $data = [];
                //完成节省内存后取消设置批量响应
                unset($result);
            }
        }
        if(!empty($data)){
//            $result = $mongo->insertAll($data);
        }
    }
}